/**
 * File: ArcMultiplicityCutoff.java
 * Created by: mhaimel
 * Created on: Mar 24, 2010
 * CVS:  $Id: ArcMultiplicityCutoff.java 1.0 Mar 24, 2010 11:57:35 AM mhaimel Exp $
 */
package uk.ac.ebi.curtain.model.graph.curtain.filter;

import java.util.concurrent.atomic.AtomicIntegerArray;

import uk.ac.ebi.curtain.model.graph.Arc;
import uk.ac.ebi.curtain.model.graph.GraphAccess.ProcessEach;
import uk.ac.ebi.curtain.model.graph.curtain.CategoryReadInfo;
import uk.ac.ebi.curtain.model.graph.curtain.ContigInfo;
import uk.ac.ebi.curtain.model.graph.curtain.ReadWrapper;

/**
 * @author mhaimel
 *
 */
public abstract class ArcMultiplicityCutoff implements ProcessEach<Arc<ContigInfo, ReadWrapper>> {
	
	private final AtomicIntegerArray cutoff;
	
	public ArcMultiplicityCutoff(int[] cutoffCategory) {
		this.cutoff = new AtomicIntegerArray(cutoffCategory);
	}

	@Override
	public Arc<ContigInfo, ReadWrapper> process(int idx,Arc<ContigInfo, ReadWrapper> arc) {
		if(arc == null){
			return arc;
		}
		int len = cutoff.length();
		int cat = arc.getValue().getCategories();
		if(len != cat){
			throw new IllegalArgumentException("Categories ("+cat+") used do not match with cut-offs provided (" + len +"): " + cutoff.toString());
		}
		int invalidCat = 0;
		for(int i = 0; i < len; ++i){
			CategoryReadInfo info = arc.getValue().getInfo(i);
			if(null != info){
				int cut = cutoff.get(i);
				if(doCutoff(i,info,cut)){
					arc.getValue().forceSetCategoryReadInfo(i, null);
					++invalidCat;
				}
			} else {
				++invalidCat;
			}
		}
		if(cat > invalidCat){
			return arc;
		} else {
			return null;
		}
	}

	protected abstract boolean doCutoff(int category, CategoryReadInfo info, int cut); 

}
